package wechat

import (
	"baokaobang/conf"
	"baokaobang/utils"
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis/v7"
	"time"
)

// APP微信登录获取access_token
type AppAccessToken struct {
	Appid     string `json:"appid"`      // 应用唯一标识，在微信开放平台提交应用审核通过后获得
	Secret    string `json:"secret"`     // 应用密钥 AppSecret，在微信开放平台提交应用审核通过后获得
	Code      string `json:"code"`       // APP客户端传来的
	GrantType string `json:"grant_type"` // 填 authorization_code
}

// APP微信登录获取access_token
type AppAccessTokenRes struct {
	Errcode      int    `json:"errcode"`
	Errmsg       string `json:"errmsg"`
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	Openid       string `json:"openid"`
	Scope        string `json:"scope"`
}

// 小程序access_token
type MiniAcessTokenRes struct {
	Errcode     int    `json:"errcode"`
	Errmsg      string `json:"errmsg"`
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
}

// 获取小程序access_token
func GetMiniAccessToken() (string, error) {
	client, err := utils.GetRedisClient()
	if err != nil {
		return "", err
	}
	redisKey := "zbzl_mini_access_token"
	accessToken, err := client.Get(redisKey).Result()
	if err == redis.Nil || err != nil {
		url := fmt.Sprintf(
			"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
			conf.MiniConfig.AppId, conf.MiniConfig.AppSecret)
		res, err := utils.GetRequest(url)
		if err != nil {
			return "", err
		}
		var data MiniAcessTokenRes
		if err := json.Unmarshal(res, &data); err != nil {
			return "", err
		}
		if data.Errcode != 0 {
			return "", utils.NewError(0, data.Errmsg)
		}
		accessToken = data.AccessToken
		client.Set(redisKey, accessToken, 6500*time.Second)
	}
	return accessToken, nil
}

func NewAppAccessToken(code string) *AppAccessToken {
	return &AppAccessToken{
		Appid:     conf.OpenWechatAppConfig.AppId,
		Secret:    conf.OpenWechatAppConfig.Secret,
		Code:      code,
		GrantType: "authorization_code",
	}
}

// APP微信登录获取access_token
func (a *AppAccessToken) Get() (*AppAccessTokenRes, error) {
	url := fmt.Sprintf(
		"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=%s",
		a.Appid, a.Secret, a.Code, a.GrantType)
	res, err := utils.GetRequest(url)
	if err != nil {
		return nil, err
	}
	var data AppAccessTokenRes
	if err := json.Unmarshal(res, &data); err != nil {
		return nil, err
	}
	return &data, nil
}
